/*
 * @Author: Smthie Smthie@qq.com
 * @Date: 2024-05-21 11:38:20
 * @LastEditors: Smthie Smthie@qq.com
 * @LastEditTime: 2024-05-31 16:18:56
 * @FilePath: \ProtocolTool\src\renderer\src\store\modules\oneClick.ts
 */
import { defineStore } from 'pinia'
import { useSocketStoreHook } from '@/store/modules/websocket'
import { MQTTTestAPI, socketTestAPI, stopTestAPI } from '@/api/OneClick'

const useSocketStore = useSocketStoreHook()

const useTestStore = defineStore('test', {
  state: () => {
    return {
      status: '',
      testItemList: {
        // MQTT 测试项
        1: {
          id: 1,
          label: '测量数据',
          desc: '通过指令的方式获取地球物理专用设备的测量数据。'
        },
        2: {
          id: 2,
          label: '获取工作参数',
          desc: '通过指令的方式获取地球物理专用设备的工作参数。'
        },
        3: {
          id: 3,
          label: '状态信息',
          desc: '通过指令的方式获取地球物理专用设备的状态信息。'
        },
        4: {
          id: 4,
          label: '告警信息',
          desc: '通过指令的方式获取地球物理专用设备的告警信息。'
        },
        5: {
          id: 5,
          label: '运行日志',
          desc: '通过指令的方式获取地球物理专用设备的日志数据。'
        },
        6: {
          id: 6,
          label: '获取属性信息',
          desc: '通过指令的方式获取地球物理专用设备的属性信息。'
        },
        7: {
          id: 7,
          label: '设置工作参数',
          desc: '通过指令的方式设置地球物理专用设备的工作参数。'
        },
        8: {
          id: 8,
          label: '设备控制',
          desc: '通过指令的方式控制地球物理专用设备。'
        },
        9: {
          id: 9,
          label: '审核结果',
          desc: '向地球物理专用设备发送进网审核结果。'
        },
        10: {
          id: 10,
          label: '设备入网',
          desc: '向地球物理专用设备发送入网审批结果，测试设备响应情况'
        },
        // Socket 测试项
        21: {
          id: 21,
          label: '整体测量数据',
          desc: '通过指令方式获取地球物理专用设备的测量数据。'
        },
        22: {
          id: 22,
          label: '实时测量数据',
          desc: '获取地球物理专用设备实时产生的测量数据。'
        },
        23: {
          id: 23,
          label: '当前测量数据',
          desc: '通过指令方式获取地球物理专用设备最近整5分钟的测量数据。'
        },
        24: {
          id: 24,
          label: '运行日志',
          desc: '通过指令的方式获取地球物理专用设备的日志信息。'
        },
        25: {
          id: 25,
          label: '获取工作参数',
          desc: '通过指令方式获取地球物理专用设备的工作参数。'
        },
        26: {
          id: 26,
          label: '设置工作参数',
          desc: '通过指令方式设置地球物理专用设备的工作参数。'
        },
        27: {
          id: 27,
          label: '获取状态信息',
          desc: '通过指令的方式获取地球物理专用设备的状态信息。'
        },
        28: {
          id: 28,
          label: '获取属性信息',
          desc: '通过指令的方式获取地球物理专用设备的属性信息。'
        },
        29: {
          id: 29,
          label: '更新固件代码',
          desc: '通过指令的方式更新地球物理专用设备的固件代码。'
        },
        30: {
          id: 30,
          label: '用户登录',
          desc: '通过指令方式输入用户名和密码后，登录地球物理专用设备。'
        },
        31: {
          id: 31,
          label: '修改密码',
          desc: '通过指令方式修改地球物理专用设备的密码。'
        },
        32: {
          id: 32,
          label: '设备控制',
          desc: '通过指令的方式控制地球物理专用设备。'
        },
        33: {
          id: 33,
          label: '事件记录测量数据',
          desc: '客户端通过指令获取由数据传输参数指定的任意一天或几天的事件记录测量数据。'
        }
      },
      topic: null as any,
      testInfo: {} as any,
      currentStepObj: {} as any,
      commandTestQueue: [] as any,
      liveTestQueue: [] as any,
      socketTestQueue: [] as any
    }
  },
  actions: {
    // 获取MQTT测试队列顺序
    getSequence(seq) {
      if (seq.includes('&')) {
        return {
          commantSeq: JSON.parse(seq.split('&')[0]),
          liveSeq: JSON.parse(seq.split('&')[1])
        }
      } else {
        return {
          commantSeq: JSON.parse(seq),
          liveSeq: []
        }
      }
    },
    // 启动订阅
    subscribe() {
      this.topic = useSocketStore.stompClient.subscribe('/topic/oneKey', (msg: any) => {
        const res = JSON.parse(msg.body)
        console.log(res)
        // 更新测试子项
        if (res.testItem.testItem === this.currentStepObj.id) {
          const oldItem = this.currentStepObj.items.find(
            (item: any) => item.id === res.testItem.itemId
          )
          if (oldItem) {
            oldItem.desc = res.testItem.result
            oldItem.status = res.testItem.resultStatus
            oldItem.requestData = res.testItem.requestData
            oldItem.responseData = res.testItem.responseData
          } else {
            this.currentStepObj.items.push({
              id: res.testItem.itemId,
              label: res.testItem.itemName,
              desc: res.testItem.result,
              status: res.testItem.resultStatus,
              requestData: res.testItem.requestData,
              responseData: res.testItem.responseData
            })
          }
        }
        // 更新当前步骤
        if (res.testInfo.runStep !== this.currentStepObj.id) {
          const hasErr = this.currentStepObj.items.some((item: any) => item.status === 99)
          this.currentStepObj.status = hasErr ? -1 : 1
          if (this.testInfo.protocolType === 'Socket') {
            this.currentStepObj = this.socketTestQueue.find(
              (item: any) => item.id === res.testInfo.runStep
            )
          } else if (res.testInfo.runTransport) {
            this.currentStepObj = this.commandTestQueue.find(
              (item: any) => item.id === res.testInfo.runStep
            )
          } else {
            this.currentStepObj = this.liveTestQueue.find(
              (item: any) => item.id === res.testInfo.runStep
            )
          }
          this.currentStepObj.status = 0
        }
        // 测试完成
        if (res.testInfo.resultStatus === 100) {
          const hasErr = this.currentStepObj.items.some((item: any) => item.status === 99)
          this.currentStepObj.status = hasErr ? -1 : 1
          // console.log('测试完成!')
          this.status = 'finish'
          this.unsubscribe()
        }
      })
    },
    // 取消订阅
    unsubscribe() {
      this.topic?.unsubscribe()
    },
    // 一键测试
    async startMQTTTest(clientId) {
      this.resetTest()
      // 开启订阅
      this.subscribe()
      try {
        // 启动一键测试
        const { data } = await MQTTTestAPI({ clientId })
        this.testInfo = data
        this.status = 'active'
        const { commantSeq, liveSeq } = this.getSequence(this.testInfo.runSeq)
        // 初始化指令队列
        commantSeq.forEach((item: any) => {
          this.commandTestQueue.push({
            ...this.testItemList[item],
            status: null,
            items: []
          })
        })
        // 初始化实时队列
        liveSeq.forEach((item: any) => {
          this.liveTestQueue.push({
            ...this.testItemList[item],
            status: null,
            items: []
          })
        })
        // 设置当前步骤对象
        this.currentStepObj = this.commandTestQueue.find(
          (item: any) => item.id === this.testInfo.runStep
        )
        this.currentStepObj.status = 0
        return Promise.resolve(true)
      } catch (error) {
        // 启动失败，取消订阅
        this.unsubscribe()
        return Promise.reject(false)
      }
    },

    // Socket一键测试
    async startSocketTest(clientId) {
      this.resetTest()
      // 开启订阅
      this.subscribe()
      try {
        // 启动一键测试
        const res = await socketTestAPI({ clientId })
        this.testInfo = res.data
        this.status = 'active'
        const socketSeq = JSON.parse(this.testInfo.runSeq)
        // 初始化Socket队列
        socketSeq.forEach((item: any) => {
          this.socketTestQueue.push({
            ...this.testItemList[item],
            status: null,
            items: []
          })
        })
        console.log(this.socketTestQueue)
        // 设置当前步骤对象
        this.currentStepObj = this.socketTestQueue.find(
          (item: any) => item.id === this.testInfo.runStep
        )
        this.currentStepObj.status = 0
        return Promise.resolve(true)
      } catch (error) {
        console.log(error)
        // 启动失败，取消订阅
        this.unsubscribe()
        return Promise.reject(false)
      }
    },

    // 终止测试
    stopTest() {
      this.status = 'stop'
      this.unsubscribe()
      stopTestAPI({ testId: this.testInfo.testId })
      const currentItem = this.currentStepObj.items.find((item: any) => item.status === 1)
      if (currentItem) {
        currentItem.desc = '已取消'
      }
      this.currentStepObj.status = -99
    },
    // 重置测试
    resetTest() {
      this.$reset()
    }
  },
  getters: {
    // 总测试项数量
    stepCount: (state) => {
      if (state.testInfo.protocolType === 'Socket') {
        return state.socketTestQueue.length
      } else {
        return state.commandTestQueue.length + state.liveTestQueue.length
      }
    },
    // 已测试项数量
    testedStepCount: (state) => {
      if (state.testInfo.protocolType === 'Socket') {
        return state.socketTestQueue.filter((item: any) => item.status !== null).length
      } else {
        return (
          state.commandTestQueue.filter((item: any) => item.status !== null).length +
          state.liveTestQueue.filter((item: any) => item.status !== null).length
        )
      }
    },
    // 测试异常数量
    errorStepCount: (state) => {
      if (state.testInfo.protocolType === 'Socket') {
        return state.socketTestQueue.filter((item: any) => item.status === -1).length
      } else {
        return (
          state.commandTestQueue.filter((item: any) => item.status === -1).length +
          state.liveTestQueue.filter((item: any) => item.status === -1).length
        )
      }
    }
  }
})

export default useTestStore
